/**
 * 20210823：创建，原THREE.Face3被移除
 * 20211116：新增包围球相关代码
 */
import {Vector3,Sphere} from "three";

/**
 * 数学三点面
 */
export default class Face3{
    constructor(a,b,c){
        this._a=a?a.clone():new Vector3();
        this._b=b?b.clone():new Vector3();
        this._c=c?c.clone():new Vector3();
        this._n=new Vector3();
        this._tV0=new Vector3();
        this._tV1=new Vector3();
        this._needsUpdate=true;
        this._sphere=new Sphere();
        this._userData={};
    }

    /**
     * 面的a点
     * @returns {Vector3}
     */
    get a(){
        return this._a;
    }
    set a(vec3){
        this._needsUpdate=true;
        this._a.copy(vec3);
    }

    /**
     * 面的b点
     * @returns {Vector3}
     */
    get b(){
        return this._b;
    }
    set b(vec3){
        this._needsUpdate=true;
        this._b.copy(vec3);
    }

    /**
     * 面的c点
     * @returns {Vector3}
     */
    get c(){
        return this._c;
    }
    set c(vec3){
        this._needsUpdate=true;
        this._c.copy(vec3);
    }

    /**
     * 面法线
     * @returns {Vector3}
     */
    get normal(){
        if(this._needsUpdate)this.update();
        return this._n;
    }

    /**
     * 面的包围球
     * @returns {Sphere}
     */
    get sphere(){
        if(this._needsUpdate)this.update();
        return this._sphere;
    }

    /**
     * 自定义数据储存
     * @returns {{}|*}
     */
    get userData(){
        return this._userData;
    }

    /**
     * 使用值设置面的某一顶点
     * @param component
     * @param x
     * @param y
     * @param z
     */
    setByValue(component,x,y,z){
        this._needsUpdate=true;
        switch (component) {
            case 0:
                this._a.set(x,y,z);
                break;
            case 1:
                this._b.set(x,y,z);
                break;
            case 2:
                this._c.set(x,y,z);
                break;
            case 'a':
                this._a.set(x,y,z);
                break;
            case 'b':
                this._b.set(x,y,z);
                break;
            case 'c':
                this._c.set(x,y,z);
                break;
        }
    }

    /**
     * 使用顶点索引及相应的类型化数组设置面的某一顶点
     * @param component
     * @param index
     * @param array
     */
    setByIndex(component,index,array){
        this._needsUpdate=true;
        let i=index*3;
        switch (component) {
            case 0:
                this._a.set(array[i],array[i+1],array[i+2]);
                break;
            case 1:
                this._b.set(array[i],array[i+1],array[i+2]);
                break;
            case 2:
                this._c.set(array[i],array[i+1],array[i+2]);
                break;
            case 'a':
                this._a.set(array[i],array[i+1],array[i+2]);
                break;
            case 'b':
                this._b.set(array[i],array[i+1],array[i+2]);
                break;
            case 'c':
                this._c.set(array[i],array[i+1],array[i+2]);
                break;
        }
    }

    applyMatrix4(mat4){
        this._a.applyMatrix4(mat4);
        this._b.applyMatrix4(mat4);
        this._c.applyMatrix4(mat4);
        this._needsUpdate=true;
    }

    /**
     * 更新法线
     */
    update(){
        this._tV0.subVectors(this._b,this._a);
        this._tV1.subVectors(this._c,this._a);
        this._n.crossVectors(this._tV0,this._tV1).normalize();
        this._sphere.setFromPoints([this._a,this._b,this._c]);
        this._needsUpdate=false;
    }

    /**
     * 拷贝
     * @param face
     */
    copy(face){
        this._a.copy(face.a);
        this._b.copy(face.b);
        this._c.copy(face.c);
        this._n.copy(face.normal);
        this._needsUpdate=face._needsUpdate;
    }

    /**
     * 克隆
     * @returns {Face3}
     */
    clone(){
        let c=new Face3();
        c.copy(this);
        return c;
    }
}